package com.platform.module.dao.config.db;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.platform.module.dao.config.MyBatisPlusHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.*;

@Configuration
@MapperScan(basePackages = {"com.platform.module.dao.mapper"})
@ComponentScan(value = "com.platform.module.dao.service")
@Slf4j
public class DataSourceConfig {
    @Bean(name = {"db1"})
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource dataSource1() {
        return new DruidDataSource();
    }

    @Bean(name = {"db2"})
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource dataSource2() {
        return new DruidDataSource();
    }

    @Primary
    @Bean(name = {"dynamicDataSource"})
    public DataSource dynamicDataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setDefaultTargetDataSource(this.dataSource1());
        Map<Object, Object> dsMap = new HashMap<>();
        dsMap.put("db1", this.dataSource1());
        dsMap.put("db2", this.dataSource2());
        dynamicDataSource.setTargetDataSources(dsMap);
        return dynamicDataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(this.dynamicDataSource());
    }

    @Bean
    public SqlSessionFactory primarySessionFactory(@Qualifier("dynamicDataSource") DataSource dataSource, MyBatisPlusHandler myBatisPlusHandler) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();//mybatis-plus不能用自带的SqlSessionFactoryBean
        bean.setTypeAliasesPackage("com.platform.module.dao.entity");
        bean.setDataSource(dataSource);
        bean.setMapperLocations(this.resolveMapperLocations());
        bean.setPlugins(this.paginationInterceptor());//设置mybatis-plus分页器
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setMetaObjectHandler(myBatisPlusHandler);
        bean.setGlobalConfig(globalConfig);
        return bean.getObject();
    }

    /**
     * MyBatisPlus拦截器（用于分页）
     */
    @Bean
    public MybatisPlusInterceptor paginationInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //添加MySQL的分页拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //添加乐观锁
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

    @Bean
    public Resource[] resolveMapperLocations() {
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        List<String> mapperLocations = new ArrayList<>();
        mapperLocations.add("classpath*:mapper/*.xml");
        List<Resource> resources = new ArrayList<>();
        for (String mapperLocation : mapperLocations) {
            try {
                Resource[] mappers = resourceResolver.getResources(mapperLocation);
                resources.addAll(Arrays.asList(mappers));
            } catch (IOException e) {
                log.error("DaoConfig.resolveMapperLocations -> 获取mapper/*.xml失败", e);
            }
        }
        return resources.toArray(new Resource[resources.size()]);
    }
}
